#include "StdAfx.h"
#include "InputManager.h"


// Forward declaration
int convertWParamToKeyboardValue(WPARAM _key);
int convertUINTToMouseValue(UINT _key);

namespace FEngine
{
	InputManager* InputManager::mInstance = NULL;

	InputManager::InputManager()
	{
		mVectorKeyDown			= std::vector<bool>(KEYBOARD_ENUM_MAX_VALUE, false);
		mVectorMouseButtonDown	= std::vector<bool>(MOUSE_ENUM_MAX_VALUE, false);
		mMousePosition			= Vector2(0, 0);
	}


	void InputManager::_keyDown(WPARAM _key)
	{
		int key = convertWParamToKeyboardValue(_key);

		if (mVectorKeyDown[key])
			return;

		mVectorKeyDown[key] = true;

		for (std::list<KeyboardInputListener*>::iterator it = mListKeyboardInputListener.begin(); it != mListKeyboardInputListener.end(); ++it)
			(*it)->keyPressed(key);
	}

	void InputManager::_keyUp(WPARAM _key)
	{
		int key = convertWParamToKeyboardValue(_key);
		
		if (!mVectorKeyDown[key])
			return;

		mVectorKeyDown[key] = false;

		for (std::list<KeyboardInputListener*>::iterator it = mListKeyboardInputListener.begin(); it != mListKeyboardInputListener.end(); ++it)
			(*it)->keyReleased(key);
	}
	
	void InputManager::_mouseButtonDown(WPARAM _but, const Vector2& _pos)
	{
		int but = convertUINTToMouseValue(_but);

		if (mVectorMouseButtonDown[but])
			return;

		mVectorMouseButtonDown[but] = true;

		for (std::list<MouseInputListener*>::iterator it = mListMouseInputListener.begin(); it != mListMouseInputListener.end(); ++it)
			(*it)->mouseButtonPressed(but, _pos);
	}

	void InputManager::_mouseButtonUp(WPARAM _but, const Vector2& _pos)
	{
		int but = convertUINTToMouseValue(_but);

		if (!mVectorMouseButtonDown[but])
			return;

		mVectorMouseButtonDown[but] = false;
		
		for (std::list<MouseInputListener*>::iterator it = mListMouseInputListener.begin(); it != mListMouseInputListener.end(); ++it)
			(*it)->mouseButtonReleased(but, _pos);
	}
	
	void InputManager::_mouseMove(const Vector2& _pos)
	{
		if (mMousePosition == _pos)
			return;

		Vector2 delta = _pos - mMousePosition;
		mMousePosition = _pos;
		
		for (std::list<MouseInputListener*>::iterator it = mListMouseInputListener.begin(); it != mListMouseInputListener.end(); ++it)
			(*it)->mouseMoved(delta);
	}

	
	bool InputManager::isKeyDown(Keyboard _key) const
	{
		return mVectorKeyDown[_key];
	}

	bool InputManager::isKeyUp(Keyboard _key) const
	{
		return !mVectorKeyDown[_key];
	}
	
	bool InputManager::isMouseButtonDown(Mouse _but) const
	{
		return mVectorMouseButtonDown[_but];
	}

	bool InputManager::isMouseButtonUp(Mouse _but) const
	{
		return !mVectorMouseButtonDown[_but];
	}
	
	Vector2 InputManager::getMousePosition() const
	{
		return mMousePosition;
	}

	
	void InputManager::registerKeyboardInputListener(KeyboardInputListener* _keyboard)
	{
		mListKeyboardInputListener.push_back(_keyboard);
	}

	void InputManager::unregisterKeyboardInputListener(KeyboardInputListener* _keyboard)
	{
		mListKeyboardInputListener.remove(_keyboard);
	}
	
	void InputManager::registerMouseInputListener(MouseInputListener* _mouse)
	{
		mListMouseInputListener.push_back(_mouse);
	}

	void InputManager::unregisterMouseInputListener(MouseInputListener* _mouse)
	{
		mListMouseInputListener.remove(_mouse);
	}

} // namespace FEngine

int convertWParamToKeyboardValue(WPARAM _key)
{
	// a->z
	if (_key >= 65 && _key <= 90)
		return FEngine::InputManager::KEY_A + _key - 65;

	// Directional arrows
	if (_key >= 37 && _key <= 40)
		return FEngine::InputManager::KEY_LEFT + _key - 37;
	
	// 0->9
	if (_key >= 96 && _key <= 105)
		return FEngine::InputManager::KEY_0 + _key - 96;

	if (_key == 32)
		return FEngine::InputManager::KEY_SPACE;

	if (_key == 16)
		return FEngine::InputManager::KEY_SHIFT;
	
	if (_key == 20)
		return FEngine::InputManager::KEY_CAPSLOCK;

	if (_key == 17)
		return FEngine::InputManager::KEY_CTRL;
	
	if (_key == 19)
		return FEngine::InputManager::KEY_TAB;
	
	if (_key == 13)
		return FEngine::InputManager::KEY_ENTER;
	
	if (_key == 27)
		return FEngine::InputManager::KEY_ESCAPE;

	return 0;
}

int convertUINTToMouseValue(UINT _but)
{
	if (_but == 513 ||_but == 514)
		return FEngine::InputManager::MS_LEFTBUTTON;
	
	if (_but == 519 || _but == 520)
		return FEngine::InputManager::MS_MIDDLEBUTTON;
	
	if (_but == 516 || _but == 517)
		return FEngine::InputManager::MS_RIGHTBUTTON;

	return 0;
}